package com.efrei.uchat.client;

import java.util.Observable;
import java.util.Observer;

import org.apache.log4j.Logger;

import com.efrei.uchat.client.UChatClient.UChatStatus;
import com.efrei.uchat.message.CroomMessage;
import com.efrei.uchat.message.CroomUsersMessage;
import com.efrei.uchat.message.CroomsMessage;
import com.efrei.uchat.message.Headers;
import com.efrei.uchat.message.LoginMessage;
import com.efrei.uchat.message.Message;
import com.efrei.uchat.message.TextMessage;
import com.efrei.uchat.model.croom.CroomMessageStatus;

public abstract class UChatUI extends Observable implements Observer, IUChatClient, IUChatUI {

	private static Logger logger = Logger.getLogger(UChatUI.class);
	
	private UChatClient uChatClient;

	public UChatUI() {
	}
	
	@Override
	public void update(Observable o, Object arg) {
		if(o instanceof UChatClient) {
			Message message = (Message) arg;
			
			if(message==null) {
				logger.debug("INFO: client send null message, disconnect");
				disconnect();
				return;
			}
			
			logger.info("UChatUI: dispatch "+message);
			switch (message.getType()) {
			case CROOM_LIST_MESSAGE:
				receivedCroomList((CroomsMessage) message);
				break;
			case CROOM_USERS_MESSAGE:
				receivedCroomUsers((CroomUsersMessage) message);
				break;
			case TEXT_CHANNEL:
				receivedTextMessage((TextMessage) message);
				break;
			case LOGIN:
				receivedLoginMessage((LoginMessage) message);
				break;
			case CROOM_MESSAGE:
				croomResult((CroomMessage) message);
				break;
			default:
				logger.error("Unknown message "+message.toString());
				break;
			}
		}
	}
	
	/*
	 * received messages
	 * see IUChatClient
	 */
	
	/*
	 * send requests
	 */
	
	@Override
	public void sendMessage(String croom, String text) {
		send(Headers.TEXT_CHANNEL, new Object[] {croom, text});
	}

	@Override
	public void joinCroom(String croom) {
		send(Headers.CROOM_MESSAGE, new Object[] {CroomMessageStatus.JOIN, croom, null});
	}
	
	@Override
	public void joinCroom(String croom, String password) {
		send(Headers.CROOM_MESSAGE, new Object[] {CroomMessageStatus.JOIN, croom, password});
	}
	
	@Override
	public void leaveCroom(String croom) {
		send(Headers.CROOM_MESSAGE, new Object[] {CroomMessageStatus.LEAVE, croom, null});
	}
	
	@Override
	public void loginRequest(String login) {
		send(Headers.LOGIN, new Object[] {login});
	}
	
	@Override
	public void getCroomsList() {
		send(Headers.CROOM_LIST_MESSAGE, null);
	}
	
	@Override
	public void getCroomUsers(String croom) {
		send(Headers.CROOM_USERS_MESSAGE, new Object[] {croom});
	}
	
	private void send(Headers type, Object[] args) {
		setChanged();
		notifyObservers(new RequestMessage(type, args));
	}
	
	/*
	 * context
	 */
	
	public UChatClient getuChatClient() {
		return uChatClient;
	}
	
	/**
	 * set client's logic.
	 * @param uChatClient null for disconnect
	 */
	public void setUChatClient(UChatClient uChatClient)  {
		if(uChatClient==null) {
			if(this.uChatClient!=null) {
				logger.debug("close and delete UChatClient "+this.uChatClient);
				try {
					if(getContextStatus()!=UChatClient.UChatStatus.DISCONNECT)
						this.uChatClient.closeConnection();
				} catch(Exception e) {
					logger.error("invalid closeConnection", e);
				}
				deleteObservers();
			}
			this.uChatClient = null;
		} else {
			this.uChatClient = uChatClient;
	
			// read context messages
			uChatClient.addObserver(this);
			addObserver(uChatClient);
		}
	}
	
	public UChatStatus getContextStatus() {
		return uChatClient.getStatus();
	}
	
	public UChatClient getContext() {
		return uChatClient;
	}
}
